#include "p2head.h"
#include <stdlib.h>
#include <string> 
using namespace std;
extern cashierCounterMonitor CCM;
extern cashierPatientMonitor CPM;
extern int testcontrol;

#define REGISTRATIONFEE 5.0
#define BASICEXAMFEE 10.0
#define SHOTFEE 15.0
#define XRAYFEE 8.0

float calculateMedicalFee(struct examSheet* examSheet)
{
      float sum = REGISTRATIONFEE + BASICEXAMFEE;
      if(examSheet->shot ==1){sum+= SHOTFEE;}
      sum+= XRAYFEE * examSheet->xray;
      return sum;
}

string floatToString(float f)
{
       char temp[10];
       sprintf(temp,"%f", f);
       return temp;
}

string intToString(int i)
{
       char temp[10];
       sprintf(temp,"%d", i);
       return temp;
}
string printAReceipt(struct examSheet* examSheet, float fee)
{
       string str = "           RECEIPT             \n";
       str=str+ "--------------------------\n";
       str=str+ "Name: patient[" + intToString(examSheet->name) + "]\n";
       str=str+ "Registration Fee: " + floatToString(REGISTRATIONFEE) +"\n";
       str=str+ "Basic Examination Fee: " +floatToString(BASICEXAMFEE) + "\n";
       str=str+ "Shot Fee: ";
       if(examSheet->shot ==1)
       {
            str=str+ floatToString(SHOTFEE) ;
       }
       else
       {
           str=str+ floatToString(0);
       }
       str=str+ "\n";
       str=str+ "XRay Fee: "+ floatToString(XRAYFEE * (examSheet->xray)) + "\n";
       str=str+ "Total: " + floatToString(fee) +"\n";
       return str;
}



void cashier(){

	//printf("I'm a cashier.\n");
	float medicalFee = 0;        //for the amount of money caculated from the examsheet
	struct examSheet* examSheetforFee;
	float cashierReceives = 0;        //for the amount of money the patient give the cashier
	while(true)
	{
         
         CCM.cashierCounterLock->Acquire();
         if(CCM.cashierWaitedCount > 0)//There are 1 or more patient are waiting for paying there medical fee
         {
            CCM.cashierCounterCV->Signal(CCM.cashierCounterLock);
            CCM.cashierWaitedCount --;
            CCM.cashierState = false;
         }        
         else{CCM.cashierState = true;}
         
         CPM.cashierPatientLock->Acquire();
         CCM.cashierCounterLock->Release();
         CPM.cashierPatientCV->Wait(CPM.cashierPatientLock);
         
         examSheetforFee = CPM.cashierExamSheet;
         if(examSheetforFee->patientType == 1)
         {
         	
			if(testcontrol==3||testcontrol==7)
             printf("Cashier receives the examination sheet from Adult Patient [%d].\n",CPM.cashierExamSheet->name);
             CPM.medicalFee = calculateMedicalFee(examSheetforFee);
			
			if(testcontrol==3||testcontrol==7)
			 printf("Cashier reads the examination sheet of Adult Patient [%d] and asks him to pay $[%f].\n",CPM.cashierExamSheet->name,CPM.medicalFee);
             CPM.cashierPatientCV->Signal(CPM.cashierPatientLock);
             CPM.cashierPatientCV->Wait(CPM.cashierPatientLock);
             
             cashierReceives = CPM.moneyPatientPay;
			
			if(testcontrol==3||testcontrol==7)
             printf("Cashier accepts $[%f] from Adult Patient [%d].\n",cashierReceives,CPM.cashierExamSheet->name);
             CPM.receipt = printAReceipt(examSheetforFee, cashierReceives); 
			
			if(testcontrol==3||testcontrol==7)
             printf("Cashier gives a receipt of $[%f] to Adult Patient [%d].\n",cashierReceives,CPM.cashierExamSheet->name);
             CPM.cashierPatientCV->Signal(CPM.cashierPatientLock);
             CPM.cashierPatientLock->Release();
         }
         else{
			 if(testcontrol==3||testcontrol==7)	
	             printf("Cashier receives the examination sheet from Child Patient [%d] from Parent [%d].\n",CPM.cashierExamSheet->name,CPM.cashierExamSheet->name);
             CPM.medicalFee = calculateMedicalFee(examSheetforFee);
			
			if(testcontrol==3||testcontrol==7)
			 printf("Cashier reads the examination sheet of Child Patient [%d] and asks Parent [%d] to pay $[%f].\n",CPM.cashierExamSheet->name,CPM.cashierExamSheet->name,CPM.medicalFee);
             CPM.cashierPatientCV->Signal(CPM.cashierPatientLock);
             CPM.cashierPatientCV->Wait(CPM.cashierPatientLock);
             
             cashierReceives = CPM.moneyPatientPay;
			
			if(testcontrol==3||testcontrol==7)
			 printf("Cashier accepts $[%f] from Parent [%d].\n",cashierReceives,CPM.cashierExamSheet->name);
             CPM.receipt = printAReceipt(examSheetforFee, cashierReceives); 
			
			if(testcontrol==3||testcontrol==7)
             printf("Cashier gives a receipt of $[%f] to Parent [%d].\n",cashierReceives,CPM.cashierExamSheet->name);
             CPM.cashierPatientCV->Signal(CPM.cashierPatientLock);
             CPM.cashierPatientLock->Release();
         }
         //end of cashier's interaction with current patient
    }//end of while

}

